package gui;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.text.ParseException;

import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class MainGUI extends JFrame {

	private JTabbedPane tabbedPane;
	private MyTasksPanel myTasksPanel;
	private CompletedTasksPanel completedTasksPanel;
	private OverdueTasksPanel overdueTasksPanel;
	private HelpPanel helpPanel;
	private UserCommand userCommand;
	private Image iconImage,frameImage;
	private SystemTray sysTray;
	private PopupMenu menu;
	private MenuItem exit, forgetMeNot;
	private TrayIcon trayIcon;
	private Observer observer;
	private JPanelWithBackground background;
	private int theme = 1;

	private JPanel mainPanel;
	private JLayeredPane layeredPane;
	private JPanel tempPanel;
	private TodayEventsPanel todayEvents;

	public MainGUI() throws ParseException, IOException {
		ImagesDirectory.setTheme(theme);
		loadGUI();
		observer = Observer.getInstance();
	}

	public void loadGUI() {
		
		setGUIEnvironment();
		trayIconGUI();

		UIManager.put("TabbedPane.contentOpaque", false);
		tabbedPane = new JTabbedPane();
		setUpAllPanels();
		setUpTabbedEnvironment();
		tabbedPane.setBounds(0, 0, Dimensions._windowWidth,
				Dimensions._windowHeight);
		tabbedPane.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent evt) {
				JTabbedPane pane = (JTabbedPane) evt.getSource();
				int index = pane.getSelectedIndex();
				setIndex(index);
			}
		});

		userCommand = UserCommand.getInstance();
		userCommand.setBounds(0, 0, Dimensions._windowWidth,
				Dimensions._windowHeight);

		background = new JPanelWithBackground(ImagesDirectory.getBackground());
		background.setPreferredSize(new Dimension(getWidth(), getHeight()));

		layeredPane = new JLayeredPane();
		layeredPane.add(background, new Integer(0));

		mainPanel = new JPanel(new BorderLayout());
		setMainPanelEnvironment();

		todayEvents = TodayEventsPanel.getInstanceOf();
		JPanel temp = new JPanel(new GridBagLayout());
		temp.setOpaque(false);
		GridBagConstraints c = new GridBagConstraints();

		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.5;
		c.gridx = 0;
		c.gridy = 0;
		temp.add(tabbedPane, c);

		todayEvents = TodayEventsPanel.getInstanceOf();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 0.5;
		c.gridx = 1;
		c.gridy = 0;
		temp.add(todayEvents, c);

		mainPanel.add(userCommand, BorderLayout.SOUTH);
		mainPanel.add(temp, BorderLayout.CENTER);

		layeredPane.add(mainPanel, new Integer(1));

		background.setBounds(0, 0, Dimensions._windowWidth,
				Dimensions._windowHeight);

		tempPanel = new JPanel(new BorderLayout());
		setTempPanelEnvironment();

		setContentPane(tempPanel);
		pack();
		setVisible(true);

		// FOR EVENTS DISPATCHER
		KeyboardFocusManager.getCurrentKeyboardFocusManager()
				.addKeyEventDispatcher(new backgroundChange());

		tempPanel.addKeyListener(new KeyListener() {
			@Override
			public void keyPressed(KeyEvent arg0) {
				if (arg0.equals(KeyEvent.VK_ENTER)) {
					if (!userCommand.hasFocus()) {
						userCommand.grabFocus();
					}
				}
			}

			@Override
			public void keyReleased(KeyEvent arg0) {
				if (arg0.equals(KeyEvent.VK_ENTER)) {
					if (!userCommand.hasFocus()) {
						userCommand.grabFocus();
					}
				}
			}

			@Override
			public void keyTyped(KeyEvent arg0) {
				if (arg0.equals(KeyEvent.VK_ENTER)) {
					if (!userCommand.hasFocus()) {
						userCommand.grabFocus();
					}
				}
			}
		});
		userCommand.grabFocus();
	}
	public void updateMyTasksPanel(String[][] tasks) {
		myTasksPanel.updatePanel(tasks);
	}

	public void updateTodayEventPanel(String[][] today) {
		todayEvents.updateTodayTable(today);
	}

	public void updateCompletedTasksPanel(String[][] tasks) {
		completedTasksPanel.updatePanel(tasks);
	}

	public void updateOverdueTasksPanel(String[][] tasks) {
		overdueTasksPanel.updatePanel(tasks);
	}

	public void lightRed(String message) {
		userCommand.changeImageWhenInvalid(message);
	}

	public void lightGreen(String message) {
		userCommand.changeImageWhenValid(message);
	}

	private void setTempPanelEnvironment() {
		tempPanel.setOpaque(false);
		tempPanel.add(layeredPane, BorderLayout.CENTER);
		tempPanel.setPreferredSize(new Dimension(Dimensions._windowWidth,
				Dimensions._windowHeight));
	}

	private void setMainPanelEnvironment() {
		mainPanel.setOpaque(false);
		mainPanel.setPreferredSize(new Dimension(Dimensions._windowWidth,
				Dimensions._windowHeight));
		mainPanel.setBounds(0, 0, Dimensions._windowWidth,
				Dimensions._windowHeight);
	}

	private void setUpAllPanels() {
		myTasksPanel = new MyTasksPanel();
		tabbedPane.addTab("My Tasks", myTasksPanel);

		completedTasksPanel = new CompletedTasksPanel();
		tabbedPane.addTab("Completed Tasks", completedTasksPanel);

		overdueTasksPanel = new OverdueTasksPanel();
		tabbedPane.addTab("Overdue Tasks", overdueTasksPanel);

		helpPanel = new HelpPanel();
		tabbedPane.addTab("Help Format", helpPanel);
	}

	private void setUpTabbedEnvironment() {
		Font textFont = new Font("SansSerif", Font.BOLD, 15);

		tabbedPane.setForeground(Color.BLACK);
		tabbedPane.setBackground(new Color(153, 204, 255, 200));
		tabbedPane.setFont(textFont);

		tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
		tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
		tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);
		tabbedPane.setMnemonicAt(3, KeyEvent.VK_4);
	}

	private void trayIconGUI() {
		if (SystemTray.isSupported()) {

			sysTray = SystemTray.getSystemTray();

			iconImage = Toolkit.getDefaultToolkit().getImage(
					ImagesDirectory.iconLogo);

			menu = new PopupMenu();

			exit = new MenuItem("Exit");
			forgetMeNot = new MenuItem("ForgetMeNot");

			menu.add(exit);
			menu.add(forgetMeNot);

			exit.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					System.exit(0);
				}
			});

			forgetMeNot.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setVisible(true);
					setExtendedState(NORMAL);
				}
			});

			trayIcon = new TrayIcon(iconImage, "ForgetMeNot", menu);

			try {
				sysTray.add(trayIcon);
			} catch (AWTException e) {
				System.out.println("System Tray unsupported!");
			}
		}
	}

	private void setGUIEnvironment() {
		setSize(Dimensions._windowWidth, (int) (Dimensions._windowHeight * 0.7));
		setResizable(false);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		frameImage = Toolkit.getDefaultToolkit().getImage(ImagesDirectory.iconLogo);
	    setIconImage(frameImage);
	    setTitle("ForgetMeNot");
	}

	private void repaintBackground() {

		layeredPane.removeAll();
		layeredPane.setOpaque(false);

		background = new JPanelWithBackground(ImagesDirectory.getBackground());
		background.setPreferredSize(new Dimension(Dimensions._windowWidth,
				Dimensions._windowHeight));
		layeredPane.add(background, new Integer(0));
		background.setBounds(0, 0, Dimensions._windowWidth,
				Dimensions._windowHeight);
		layeredPane.add(mainPanel, new Integer(1));

	}

	protected void setIndex(int index) {
		observer.changeCurrentPanel(index);
	}

	private class backgroundChange implements KeyEventDispatcher {

		@Override
		public boolean dispatchKeyEvent(KeyEvent arg0) {
			if (arg0.getID() == KeyEvent.KEY_PRESSED)
				if (arg0.getKeyCode() == KeyEvent.VK_F8) {
					theme++;
					if (theme == 6)
						theme = 1;
					ImagesDirectory.setTheme(theme);
					repaintBackground();
				}
			return false;
		}
	}
}
